book

[서평] 심플 소프트웨어

13 min read|19. 11. 5.

simple_software

길벗 리뷰어로 선정되어 심플 소프트웨어 책을 받아보았다. 책을 소개하고 있는 내용 중, 'Code Health'라는 말에 이끌려 리뷰어 신청을 했다. 저자가 무려 구글의 Code Health 기술 책임자라고 한다. 책을 받았을 때 얇은 두께에 놀랐다. 이 얇은 책이 소프트웨어라는 광범위한 내용을 다룬다는 것에 의심을 했다.

이 책은 '코드의 단순성, 가독성, 안정성, 유지보수'라는 부제를 갖고 있다. 각각의 주제에 대해서 한 권의 책, 그 이상의 내용이 나올 수 있는 주제들인데 얇은 책 안에 저자의 통찰이 담겨져 있다. 저자가 프로젝트를 진행하면서 느꼈던 부분들, 경험에서 나오는 통찰들이 주제별로 묶여있다.

소프트웨어와 관련된 내용을 다루면서 우리가 실제로 작성할만한 예제 코드는 등장하지 않는다. 그렇기 때문에 실습을 위한 노트북은 필요없으며 내용에 쉽게 공감할 수 있어 빠르게 읽힌다.

인상 깊었던 Part 3 디버깅

디버깅에 대해서 이렇게 잘 다룬 책은 오랜만이었다. 처음 프로그래밍을 배울 때, 화면에 나타나는 빨간색 에러가 두려웠던 적이 있다. 어디를 고쳐야 동작하는지 모르겠고 검색을 하라는데 무엇을 검색해야 할지도 몰랐던 시절이 있었다.

지금도 디버깅음 쉽지 않다. 해결책을 아예 찾지 못해 헤메는 경우가 허다하고 해결책을 찾았다고 하더라도 이 해결책이 정말 올바른 해결책인지, 최선의 해결책인지 끊임없이 고민한다.

다음은 책에서 이야기하고 있는 디버깅에 대한 내용이다.

  1. 버그는 보통 복잡성을 줄이지 못할 때 발생한다.
  2. 무슨 작업을 해야 할지 그 코드를 어떻게 써야 할지 아주 분명하고 정확하게 알 수 없다면 누군가는 실수할 것이다. (그리고 그 실수는 버그를 유발한다.)
  3. 문제가 완전히 사라져서 다시는 발생하지 않아야 임무를 완수한 것이다.
  4. 아무도 그 문제에 다시는 주의를 기울일 필요가 없을 정도가 되어야 한다.
  5. 디버깅은 본인이 아직 답을 모른다고 자각하는 데에서 시작해야 한다.
  6. 답을 추측하지 말고 문제의 근본 원인을 찾아야 한다.

3번, 4번은 마침 진행하고 있는 프로젝트가 테스트하는 기간이라 더욱 와 닿았다. 애플리케이션이 개발 됨에 따라 복잡도는 증가하게 되고 여기 저기에서 문제가 발생하기 시작한다. 그리고 여기 저기서 해결되면서 더 복잡해진다.

과연 마주친 문제를 해결하는 것이 끝일까. 디버깅 과정이 문제를 해결하고 끝난다면, 그리고 계속 이렇게 진행된다면 그 애플리케이션은 폭탄이 된다. 아무도 건드리지 못하게 되는 것이다. 이미 해결한 문제가 언제 어디서 재발할지 아무도 모른다. 그래서 누구도 그 소스 코드를 건드리려고 하지 않는다.

해결하기 전

이 책의 저자는 우선 근본 원인을 찾아 해결하라고 한다. 예를 들어보자. 웹 환경에서 비동기 처리에 대한 문제는 정말 자주 만나는 문제 중 하나이다. 이 문제가 발생했을 때, 문제의 원인을 제대로 파악하지 않고 문제가 해결되는 현상에 취해 setTimeout과 같은 꼼수로 문제를 해결했다면 그 애플리케이션은 금방 무너지게 된다. 근본 원인을 찾아 해결한 것이 아니기 때문이다.

해결하고 난 후

근본 원인을 찾아 문제를 해결했다면 그 재현 과정을 테스트 코드를 작성해둬야 한다. 그래야 다른 개발자 또는 미래의 내가 그 부분을 수정을 했을 때, 이전에 발생했던 문제가 재발하더라도 바로 알아차릴 수 있기 때문이다.

문제를 해결한 곳이 한 두 곳일 경우에는 개발자가 기억하거나 이슈에 등록해두고 신경쓰면 되겠지만 애플리케이션에서는 수많은 문제가 발생한다. 그리고 프로젝트에 참여하는 개발자 수가 늘어날수록 문제는 심각해진다. 한 번 해결한 문제는 더이상 아무도 신경쓰지 않을 수 있도록 발생한 문제에 대해서는 테스트 코드가 반드시 필요하다.

고민을 던져준 Part 4 엔지니어링 팀에서 일하기

개발자의 생산성을 측정한다고?

어떤 플랫폼을 개발하는지, 프로덕트 개발자인지, 라이브러리 개발자인지 그 기준은 상황에 따라 다르겠지만 이 책에서 공통적으로 이야기하고 있는 것은 생산성을 측정한다는 말이었다.

측정할 수 없다면 개선할 수 없다.

피터드러커가 한 말이다. 이 부분은 '성능 개선'이라는 부분과도 일맥상통한다. 성능을 개선하려면 우선 측정부터 제대로 해야 한다. 그래야 어떠한 시도를 했을 때 얼만큼 개선됐는지 알 수 있다. 측정과 개선을 반복하면서 들어오는 피드백을 바탕으로 점진적인 발전을 할 수 있다. 성능에서는 이것이 당연하다고 생각했는데 '생산성'에서는 왜 이런 생각을 못했을까?

나름 생산성에 관심이 많다고 여러 도구를 만들어보기도 하고 고민도 했었지만 어떻게 측정하면 좋을지 고민한 적은 없었던 것 같다. 내가 지금 하고 있는 일의 생산성을 어떻게 측정할 수 있을지 고민해볼 수 있는 기회가 되었다.

생산성을 어떻게 측정할까에 대한 고민없이 Timing이라는 애플리케이션을 구매하여 사용해봤었다. 그 지표가 보기 어려워 제대로 보지 않았었다. 그리고 Chrome Browser에서 활동하는 시간을 웹 서핑하는 시간으로 분류가 되곤 하였다. (Chrome Devtools를 이용하여 디버깅하는 시간은 내 업무인데 말이다.)

측정할 수 있을까?

사람마다 기준이 다를 수 있고 측정하는 타겟이 애매하여 아직 도구가 많지 않은 것 같다. 또 이 생산성이라는 지표가 부정적으로 사용될 수도 있지 않을까 생각한다.

조금 더 나아가서 생각해보면 자동화, 리팩토링 등 실제 프로덕트의 '기능'이 아닌 업무들은 미뤄지기 쉽다. 그 성과가 제대로 측정되는 경우가 거의 없고 실상 프로덕트 스펙 쳐내기 바쁘기 때문이다. 어떠한 업무를 자동화해서 생산성 향상에 어느 정도 효과가 있었는지, 리팩토링을 통해 디버깅, 새로운 기능 추가 등의 업무 생산성에 어느 정도 효과가 있었는지 측정되면 좋을 것 같다.

얼마 전, 일본 어느 한 기업에서 주4일제를 도입했더니 생산성이 40%가 향상됐다고 한다. 어떤 근거로 어떤 기준으로 측정했을까 궁금해지는 대목이다.

Part 6 소프트웨어 이해하기에서

  • 테스트의 목적은 시스템에 대한 지식을 전달하기 위함이다.
  • 얻고자 하는 지식이 무엇인지 정확히 알아야 효과적이고 유용한 테스트를 만들 수 있다.
  • 반드시 무엇인가를 단언해야 하며 참인지 거짓인지 확인되어야 한다.
  • 테스트를 설계할 때는 테스트 대상과 테스트에 속하지 않는 부분을 정확히 구분해야 한다.
  • 모든 테스트는 가정이 내재되어 있으며 이는 해당 테스트의 범위 안에서 유효한 결과를 내는 데 꼭 필요한 전제이다.

저자가 테스트에 대해 이야기하고 있는 내용 중 일부분을 발췌해봤다. 너무나도 당연한 이야기처럼 들리지만 뭔가 이렇게 표현을 해놓고 보니 테스트의 본질을 이야기하는 것 같았다.

테스트 코드에 대한 고민

테스트 코드를 작성할 때면 늘 같은 고민에 빠진다.

  • 지금 작성한 테스트 케이스가 나에게 안정감을 줄 수 있는가?
  • 모든 케이스를 대응할 수 있을 정도로 충분한가?
  • 구현과 의존성이 너무 심한 것은 아닌가?

정확히 어떠한 환경에서 어떤 테스트를 구현할 수 있는지 구현해야 하는지 이야기하고 있지는 않지만 테스트의 본질에 대해서 잘 설명하고 있는 것 같다. 하지만 테스트에 대해 집중해서 다루는 책도 아니고 그런 chapter도 아니어서 가볍게 테스트가 무엇인지 이해할 수 있는 정도의 장이었다.

총평

  • 좀 더 깊은 내용들에 대해 알고 싶다면 각각 주제의 다른 책들이 더 좋지 않을까?
  • 저자의 다른 책 중 한빛미디어에서 출판한 Code Simplicity라는 책이 궁금해졌다.
  • 얇고 빠르게 읽을 수 있어서 정리용, 입문용으로 추천할 것 같다.